// @ts-nocheck - 腾讯地图API动态加载，忽略类型检查
import React, { useEffect, useRef, useState } from 'react';
import { MAP_CONFIG, getMapScriptUrl, getIpLocationUrl } from '../config/map';
import './TencentMap.css';

const TencentMap = ({ onLocationChange, orderPolyline }) => {
  const mapRef = useRef(null);
  const mapInstance = useRef(null);
  const [currentLocation, setCurrentLocation] = useState(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);
  const [mapLoaded, setMapLoaded] = useState(false);
  const [scriptLoading, setScriptLoading] = useState(false);
  // 请求锁，防止同一时间发起多个地理编码请求
  const geocodeLock = useRef(false);
  // 请求队列，存储待解析的地址
  const geocodeQueue = useRef([]);

  useEffect(() => {
    // 检查是否已经加载过腾讯地图脚本
    if (window.TMap) {
      setMapLoaded(true);
      initMap();
      return;
    }

    // 防止重复加载脚本
    if (scriptLoading) return;
    setScriptLoading(true);

    // 动态加载腾讯地图脚本
    const script = document.createElement('script');
    script.src = getMapScriptUrl();
    script.async = true;
    script.defer = true;

    script.onload = () => {
      // 等待一段时间确保API完全初始化
      setTimeout(() => {
        if (window.TMap) {
          setMapLoaded(true);
          setScriptLoading(false);
          initMap();
        } else {
          setError('地图API初始化失败，请刷新页面重试');
          setLoading(false);
          setScriptLoading(false);
        }
      }, 1000);
    };

    script.onerror = (error) => {
      console.error('腾讯地图脚本加载失败:', error);
      setError('地图加载失败，请检查网络连接');
      setLoading(false);
      setScriptLoading(false);
    };

    // 设置超时处理
    const timeout = setTimeout(() => {
      if (!window.TMap) {
        console.error('腾讯地图脚本加载超时');
        setError('地图加载超时，请检查网络连接');
        setLoading(false);
        setScriptLoading(false);
      }
    }, 15000); // 15秒超时

    document.head.appendChild(script);

    return () => {
      clearTimeout(timeout);
      // 清理脚本
      if (script.parentNode) {
        script.parentNode.removeChild(script);
      }
      // 清理地图实例
      if (mapInstance.current) {
        try {
          // 清除所有标记
          if (mapInstance.current.markers) {
            mapInstance.current.markers.forEach(marker => {
              if (marker && typeof marker.remove === 'function') {
                marker.remove();
              }
            });
          }
          // 销毁地图实例
          if (mapInstance.current.destroy) {
            mapInstance.current.destroy();
          }
        } catch (error) {
          console.error('清理地图实例失败:', error);
        }
        mapInstance.current = null;
      }
    };
  }, []);

  useEffect(() => {
    // 如果有订单连线信息，将地址解析请求加入队列
    if (mapLoaded && orderPolyline && orderPolyline.from && orderPolyline.to) {
      // 检查上一次的 orderPolyline 是否和当前一致
      if (
        !prevOrderPolyline.current ||
        prevOrderPolyline.current.from !== orderPolyline.from ||
        prevOrderPolyline.current.to !== orderPolyline.to
      ) {
        geocodeQueue.current.push({
          type: 'order',
          from: orderPolyline.from,
          to: orderPolyline.to,
          callback: (fromCoord, toCoord) => {
            if (fromCoord && toCoord) {
              drawOrderPolylineAfterGeocode(fromCoord, toCoord);
            } else {
              setError('地址解析失败，请检查订单地址');
            }
          }
        });
        // 启动请求队列处理
        processGeocodeQueue();
        prevOrderPolyline.current = orderPolyline;
      }
    }
  }, [mapLoaded, orderPolyline]);

  // 用于存储上一次的 orderPolyline
  const prevOrderPolyline = useRef(null);

  const initMap = () => {
    if (!window.TMap) {
      console.error('腾讯地图API未加载');
      setError('地图API未加载，请刷新页面重试');
      setLoading(false);
      return;
    }

    try {
      // 等待DOM元素准备就绪
      if (!mapRef.current) {
        console.error('地图容器未准备就绪');
        setError('地图容器未准备就绪');
        setLoading(false);
        return;
      }

      // 清空地图容器，防止重叠
      mapRef.current.innerHTML = '';

      // 创建地图实例 - 使用GL版本
      mapInstance.current = new window.TMap.Map(mapRef.current, {
        center: new window.TMap.LatLng(MAP_CONFIG.DEFAULT_CENTER.lat, MAP_CONFIG.DEFAULT_CENTER.lng),
        zoom: MAP_CONFIG.DEFAULT_ZOOM,
        viewMode: MAP_CONFIG.MAP_STYLE,
        pitch: 45, // GL版本支持倾斜角度
        rotation: 0
      });

      // 强制刷新地图，确保正确显示
      setTimeout(() => {
        if (mapInstance.current && mapInstance.current.resize) {
          mapInstance.current.resize();
        }
      }, 100);

      // 获取当前位置
      getCurrentLocation();

    } catch (error) {
      console.error('地图初始化失败:', error);
      setError(`地图初始化失败: ${error.message}`);
      setLoading(false);
    }
  };

  const getCurrentLocation = () => {
    setLoading(true);
    setError(null);

    if (navigator.geolocation) {
      navigator.geolocation.getCurrentPosition(
        (position) => {
          const { latitude, longitude } = position.coords;
          const location = { lat: latitude, lng: longitude };

          setCurrentLocation(location);

          if (mapInstance.current) {
            try {
              // 确保地图实例存在且已初始化
              if (mapInstance.current.setCenter) {
                // 移动地图到当前位置
                mapInstance.current.setCenter(new window.TMap.LatLng(latitude, longitude));

                // 添加当前位置标记
                addLocationMarker(latitude, longitude);

                // 调用回调函数
                if (onLocationChange) {
                  onLocationChange(location);
                }
              } else {
                setError('地图实例未正确初始化');
              }
            } catch (error) {
              console.error('地图操作失败:', error);
              setError('地图操作失败，请刷新页面重试');
            }
          } else {
            setError('地图实例不存在');
          }

          setLoading(false);
        },
        (error) => {
          console.error('GPS定位失败:', error);

          // 根据错误类型给出具体提示
          let errorMessage = '获取位置失败';
          switch (error.code) {
            case error.PERMISSION_DENIED:
              errorMessage = '位置权限被拒绝，请允许浏览器获取位置信息';
              break;
            case error.POSITION_UNAVAILABLE:
              errorMessage = '位置信息不可用';
              break;
            case error.TIMEOUT:
              errorMessage = '定位超时';
              break;
            default:
              errorMessage = '获取位置失败';
          }

          setError(errorMessage);
          setLoading(false);

          // 如果获取位置失败，使用IP定位作为备选方案
          getLocationByIP();
        },
        {
          enableHighAccuracy: false, // 降低精度要求，提高成功率
          timeout: 15000, // 增加超时时间
          maximumAge: 300000 // 5分钟内的位置信息都可以使用
        }
      );
    } else {
      console.error('浏览器不支持地理定位');
      setError('浏览器不支持地理定位');
      setLoading(false);
      getLocationByIP();
    }
  };

  const getLocationByIP = () => {
    fetch(getIpLocationUrl())
      .then(response => {
        if (!response.ok) {
          throw new Error(`HTTP ${response.status}`);
        }
        return response.json();
      })
      .then(data => {
        if (data.status === 0 && data.result && data.result.location) {
          const { lat, lng } = data.result.location;
          const location = { lat, lng };

          setCurrentLocation(location);
          setError(null);

          if (mapInstance.current) {
            try {
              if (mapInstance.current.setCenter) {
                mapInstance.current.setCenter(new window.TMap.LatLng(lat, lng));
                addLocationMarker(lat, lng);

                if (onLocationChange) {
                  onLocationChange(location);
                }
              }
            } catch (error) {
              console.error('地图操作失败:', error);
              setError('地图操作失败，请刷新页面重试');
            }
          }
        } else {
          throw new Error(data.message || 'IP定位失败');
        }
      })
      .catch(error => {
        console.error('IP定位失败:', error);
        setError(`IP定位失败: ${error.message}`);
      })
      .finally(() => {
        setLoading(false);
      });
  };

  const addLocationMarker = (lat, lng) => {
    if (!mapInstance.current) return;

    try {
      // 清除之前的标记
      if (mapInstance.current.markers) {
        mapInstance.current.markers.forEach(marker => {
          if (marker && typeof marker.remove === 'function') {
            marker.remove();
          }
        });
      }

      // 创建新的标记 - 使用GL版本的正确方式
      const marker = new window.TMap.MultiMarker({
        map: mapInstance.current,
        styles: {
          'marker': new window.TMap.MarkerStyle({
            width: 25,
            height: 35,
            anchor: { x: 12.5, y: 35 },
            src: 'https://mapapi.qq.com/web/lbs/javascriptGL/demo/img/markerDefault.png'
          })
        },
        geometries: [{
          'id': 'current-location',
          'styleId': 'marker',
          'position': new window.TMap.LatLng(lat, lng)
        }]
      });

      // 添加点击事件
      marker.on('click', (evt) => {
        console.log('当前位置:', { lat, lng });
      });

      // 保存标记引用
      if (!mapInstance.current.markers) {
        mapInstance.current.markers = [];
      }
      mapInstance.current.markers.push(marker);

    } catch (error) {
      console.error('添加位置标记失败:', error);
      // 如果标记创建失败，至少确保地图中心正确
      try {
        if (mapInstance.current && mapInstance.current.setCenter) {
          mapInstance.current.setCenter(new window.TMap.LatLng(lat, lng));
        }
      } catch (centerError) {
        console.error('设置地图中心失败:', centerError);
      }
    }
  };

  // 地理编码请求队列处理（带防抖的串行执行，避免并行超限）
  const processGeocodeQueue = async () => {
    // 防抖核心：如果正在处理队列或有等待中的处理任务，直接返回
    if (geocodeLock.current || queueDebounceTimer.current) return;
    // 如果队列为空，也直接返回
    if (geocodeQueue.current.length === 0) {
      queueDebounceTimer.current = null;
      return;
    }

    // 设置防抖定时器标记，避免短时间内重复触发
    queueDebounceTimer.current = setTimeout(async () => {
      // 加锁，防止并行请求
      geocodeLock.current = true;
      // 取出队列第一个请求
      const currentTask = geocodeQueue.current.shift();

      try {
        if (currentTask.type === 'order') {
          // 串行解析起点和终点（间隔500ms，避免每秒请求超量）
          const fromCoord = await getCoordsWithRetry(currentTask.from);
          // 间隔500ms再解析终点，减少每秒请求数
          await new Promise(resolve => setTimeout(resolve, 500));
          const toCoord = await getCoordsWithRetry(currentTask.to);
          // 执行回调，绘制路线
          currentTask.callback(fromCoord, toCoord);
        }
      } catch (err) {
        console.error('处理地理编码队列失败:', err);
        currentTask.callback(null, null);
      } finally {
        // 解锁，处理下一个请求
        geocodeLock.current = false;
        // 清除防抖标记
        queueDebounceTimer.current = null;
        // 递归处理队列剩余请求（带300ms延迟，进一步控制频率）
        setTimeout(processGeocodeQueue, 300);
      }
    }, 300); // 防抖延迟：300ms内重复调用会被合并
  };

  // 新增：防抖定时器引用，用于标记是否有等待中的处理任务
  const queueDebounceTimer = useRef(null);

  // 带重试机制的地理编码请求（失败后重试2次，间隔1.5秒）
  const getCoordsWithRetry = async (address, retryCount = 2, delay = 1500) => {
    // ✅ 如果是坐标对象，直接返回
    if (address && typeof address === 'object' && 'lat' in address && 'lng' in address) {
      return address;
    }
    // ✅ 否则当字符串地址处理
    const addrStr = String(address || '');
    const fetchWithTimeout = (url, options = {}, timeout = 10000) => {
      return Promise.race([
        fetch(url, options),
        new Promise((_, reject) => setTimeout(() => reject(new Error('请求超时')), timeout))
      ]);
    };

    try {
      const url = `/api/map/ws/geocoder/v1/?address=${encodeURIComponent(addrStr)}&key=${MAP_CONFIG.API_KEY}`;
      console.log('地理编码请求（重试次数:', 2 - retryCount, '）:', url);

      const res = await fetchWithTimeout(url);
      if (!res.ok) throw new Error(`HTTP状态码: ${res.status}`);

      const data = await res.json();
      // 若请求量超限，且还有重试次数，延迟后重试
      if (data.status === 120 && retryCount > 0) {
        console.log('请求量超限，延迟重试:', delay, 'ms');
        await new Promise(resolve => setTimeout(resolve, delay));
        // 重试时增加延迟时间（指数退避）
        return getCoordsWithRetry(address, retryCount - 1, delay * 1.2);
      }
      // 正常返回有效坐标
      if (data.status === 0 && data.result && data.result.location) {
        console.log('解析地址成功:', address, '→', data.result.location);
        return data.result.location;
      }
      // 其他错误（如地址无效），直接返回null
      console.error('地理编码失败:', `status=${data.status}, msg=${data.message}`);
      return null;
    } catch (err) {
      console.error('地理编码请求异常:', err);
      // 网络错误等异常，允许重试
      if (retryCount > 0) {
        console.log('请求异常，延迟重试:', delay, 'ms');
        await new Promise(resolve => setTimeout(resolve, delay));
        return getCoordsWithRetry(address, retryCount - 1, delay * 1.2);
      }
      return null;
    }
  };

  // 地址解析成功后再绘制路线
  const drawOrderPolylineAfterGeocode = (from, to) => {
    if (!window.TMap || !mapInstance.current || !from || !to) return;

    const fetchWithTimeout = (url, options = {}, timeout = 10000) => {
      return Promise.race([
        fetch(url, options),
        new Promise((_, reject) => setTimeout(() => reject(new Error('请求超时')), timeout))
      ]);
    };

    // 腾讯API返回的polyline是加密数组，需要解码
    const decodePolyline = (polyline) => {
      let list = polyline; // polyline 本身就是数组
      let coords = [];
      for (let i = 2; i < list.length; i++) {
        list[i] = list[i - 2] + list[i] / 1000000;
      }
      for (let i = 0; i < list.length; i += 2) {
        coords.push(new window.TMap.LatLng(list[i], list[i + 1]));
      }
      return coords;
    };

    try {
      // 路线规划请求
      const getRouteData = async () => {
        try {
          console.log('🚀 路线规划请求:', from, to);
          const url = `/api/map/ws/direction/v1/bicycling/?from=${from.lat},${from.lng}&to=${to.lat},${to.lng}&key=${MAP_CONFIG.API_KEY}`;
          console.log('🚀 路线规划请求:', url);

          const res = await fetchWithTimeout(url);
          if (!res.ok) throw new Error('路线规划请求失败');

          const data = await res.json();
          // 路线规划若超限，重试1次
          if (data.status === 120) {
            console.log('路线规划请求超限，延迟1秒重试');
            await new Promise(resolve => setTimeout(resolve, 1000));
            const retryRes = await fetchWithTimeout(url);
            return retryRes.json();
          }
          return data;
        } catch (err) {
          console.error('路线规划请求失败:', err);
          throw err;
        }
      };

      getRouteData().then(routeData => {
        console.log('路线数据:', routeData);

        if (routeData.status !== 0 || !routeData.result.routes[0]) {
          setError('未能获取骑行路线，请检查地址或稍后重试');
          return;
        }

        const polylineCoords = routeData.result.routes[0].polyline;
        const path = decodePolyline(polylineCoords);

        console.log('解码后的坐标数量:', path.length);
        console.log('第一个坐标:', path[0]?.getLat(), path[0]?.getLng());

        // 清除旧路线
        if (mapInstance.current.polyline) {
          mapInstance.current.polyline.setMap(null);
        }

        // 绘制新路线
        const polyline = new window.TMap.MultiPolyline({
          id: 'route',
          map: mapInstance.current,
          styles: {
            'style_blue': new window.TMap.PolylineStyle({
              color: '#1677ff',
              width: 5,
              borderWidth: 2,
              borderColor: '#fff'
            })
          },
          geometries: [{
            id: 'line',
            styleId: 'style_blue',
            paths: path
          }]
        });
        mapInstance.current.polyline = polyline;

        // 地图视角调整到路线中点
        if (path.length > 0) {
          const midIdx = Math.floor(path.length / 2);
          mapInstance.current.setCenter(path[midIdx]);
        }
      }).catch(err => {
        console.error('路线绘制失败:', err);
        setError('骑行路线规划失败，请稍后重试');
      });
    } catch (err) {
      console.error('骑行路线规划失败:', err);
      setError('骑行路线规划失败，请稍后重试');
    }
  };

  const handleRetry = () => {
    setError(null);
    setLoading(true);

    // 清理现有地图实例
    if (mapInstance.current) {
      try {
        // 清除所有标记
        if (mapInstance.current.markers) {
          mapInstance.current.markers.forEach(marker => {
            if (marker && typeof marker.remove === 'function') {
              marker.remove();
            }
          });
        }
        // 销毁地图实例
        if (mapInstance.current.destroy) {
          mapInstance.current.destroy();
        }
      } catch (error) {
        console.error('清理地图实例失败:', error);
      }
      mapInstance.current = null;
    }

    if (mapLoaded && window.TMap) {
      // 重新初始化地图
      initMap();
    } else {
      // 重新加载页面
      window.location.reload();
    }
  };

  const handleLocationClick = () => {
    console.log('📍 定位按钮被点击');
    console.log('当前状态:', { loading, currentLocation, mapInstance: !!mapInstance.current });

    if (loading) {
      console.log('正在加载中，忽略点击');
      return; // 如果正在加载，不执行操作
    }

    if (currentLocation && mapInstance.current) {
      console.log('重置地图到当前位置:', currentLocation);
      // 如果已有位置信息，重置视图到当前位置
      try {
        // 确保地图实例存在且有效
        if (mapInstance.current.setCenter && typeof mapInstance.current.setCenter === 'function') {
          mapInstance.current.setCenter(new window.TMap.LatLng(currentLocation.lat, currentLocation.lng));
          mapInstance.current.setZoom(15);
          mapInstance.current.setPitch(45);
          console.log('地图已重置到当前位置');
        } else {
          console.error('地图实例方法不可用');
          // 尝试重新初始化地图
          initMap();
        }
      } catch (error) {
        console.error('重置地图视图失败:', error);
        // 如果重置失败，尝试重新获取位置
        getCurrentLocation();
      }
    } else {
      console.log('没有位置信息或地图实例，重新获取位置');
      // 如果没有位置信息，重新获取位置
      getCurrentLocation();
    }
  };

  return (
    <div className="tencent-map-container">
      <div ref={mapRef} className="map-content" />

      {/* 定位按钮 */}
      <button
        className={`location-btn ${loading ? 'loading' : ''}`}
        onClick={handleLocationClick}
        disabled={loading}
        title={currentLocation ? '回到当前位置' : '定位当前位置'}
        style={{
          zIndex: 1000,
          pointerEvents: 'auto'
        }}
      >
        📍
      </button>

      {loading && (
        <div className="loading-overlay">
          <div className="loading-spinner"></div>
          <p>正在获取位置...</p>
        </div>
      )}

      {error && (
        <div className="error-overlay">
          <div className="error-content">
            <p>❌ {error}</p>
            <button className="retry-btn" onClick={handleRetry}>
              🔄 重试
            </button>
          </div>
        </div>
      )}
    </div>
  );
};

export default TencentMap;